package EA.testproblems;
import EA.*;

/**
This testproblem is a simple problem for initial tuning of multimodal 
optimization algorithms. <br><br>

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Six hump camel back</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Provides a difficult problem for multimodal optimization.</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">-((4 - 2.1*x<sup>2</sup> + (x<sup>4</sup>)/3)*x<sup>2</sup> + x*y + (-4+4*y<sup>2</sup>)*y<sup>2</sup>);
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/sixhumpcamelback.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/sixhumpcamelback_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-1.9:1.9]&nbsp;&nbsp;y = [-1.1:1.1] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Maximization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maximas:</b></td>
  <td valign="top">10</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minimas:</b></td>
  <td valign="top">?</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum radius:</b></td>
  <td valign="top">0.15
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum descriptions:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optimums:</b></td>
  <td valign="top">
  GMAX(0.08984201310, -0.7126564030), 
  GMAX(-0.08984201310, 0.7126564030), 
  LMAX(-1.607104753, -0.568651454),
  LMAX(1.607104753, 0.568651454),
  LMAX(1.703606715, -0.796083568),
  LMAX(-1.703606715, 0.796083568)
<br><font size=1>Capital letters 
means that the precise optimum is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 40<br>
  set view 70,15<br>
  splot [-1.9:1.9] [-1.1:1.1] -((4 - 2.1*x*x + (x*x*x*x)/3)*x*x + x*y + (-4+4*y*y)*y*y)
</td>

</tr>

</table>

*/
public class SixHumpCamelBack extends NumericalProblem
{

  // Easier way to build max and min
  private double[][] lmax = {{0.08984201310, -0.7126564030}, 
			     {-0.08984201310, 0.7126564030}, 
			     {-1.607104753, -0.5686514549},
			     {1.607104753, 0.5686514549},
			     {1.703606715, -0.7960835687},
			     {-1.703606715, 0.7960835687}};

  private double[][] lmin = new double[0][2];

  public SixHumpCamelBack()
    {
      super();

      double[] optimums;

      name = "Six hump camel back";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		  return -((4 - 2.1*realpos[0]*realpos[0] + Math.pow(realpos[0],4)/3)*realpos[0]*realpos[0] + realpos[0]*realpos[1] + (-4+4*realpos[1]*realpos[1])*realpos[1]*realpos[1]);

	      };
	  };

      dimensions = 2;
      ismaximization = true;
      optimumradius = 0.2;

      intervals = new Interval[2];
      intervals[0] = new Interval(-1.9,1.9);
      intervals[1] = new Interval(-1.1,1.1);

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[i][0];
	optimums[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[i][0];
	optimums[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, false, i);
      }
    }
}
